package com.chen.springboot.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.springboot.common.PageResult;
import com.chen.springboot.dto.*;
import com.chen.springboot.entity.Gender;
import com.chen.springboot.entity.Role;
import com.chen.springboot.entity.User;
import com.chen.springboot.exception.ServiceException;
import com.chen.springboot.mapper.UserMapper;
import com.chen.springboot.service.UserService;
import com.chen.springboot.utils.TokenUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void register(User user) {
        User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));
        if (res != null)
            throw new ServiceException("-1", "用户名已经存在，请重新输入");
        userMapper.insert(user);
    }

    @Override
    public UserDto login(User user) {
        User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));
        if (res == null)
            throw new ServiceException("404", "用户名不存在");
        if (!res.getPassword().equals(user.getPassword()))
            throw new ServiceException("404", "密码错误");
        // 生成 token，用户id保存到token里面，然后密码用于加密
        String token = TokenUtils.genToken(res.getId().toString());
        return new UserDto(res, token);
    }

    @Override
    public UserDto manageLogin(User user) {
        // 因为我们用户名是唯一的，所以给用户名加一个索引，然后通过用户名查就好了，这样效率更
        User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));
        if (res == null)
            throw new ServiceException("404", "用户名不存在");
        if (!res.getPassword().equals(user.getPassword()))
            throw new ServiceException("404", "密码错误");
//        判断用户是否是管理员
        if (res.getRole() == 3)
            throw new ServiceException("403", "当前用户没有权限访问管理端");
        // 生成 token，用户id保存到token里面，然后密码用于加密
        String token = TokenUtils.genToken(res.getId().toString());
        return new UserDto(res, token);
    }

//    @Override
//    public void save(User user) {
//        userMapper.insert(user);
//    }
    @Override
    public void saveUser(User user) {
        // 自定义保存逻辑
        this.save(user); // 依然可以调用 MyBatis-Plus 提供的 save
    }


    //    @Override
//    public void update(User user) {
//        userMapper.updateById(user);
//    }
    @Override
    public void update(User user) {
        if (user.getId() == null) {
            throw new ServiceException("400", "用户ID不能为空");
        }

        // 先查出原来的用户
        User existingUser = userMapper.selectById(user.getId());
        if (existingUser == null) {
            throw new ServiceException("404", "用户不存在");
        }

        // 仅修改前端传来的非空字段，其它字段保持原值
        if (user.getUsername() != null) existingUser.setUsername(user.getUsername());
        if (user.getPassword() != null) existingUser.setPassword(user.getPassword());
        if (user.getNickName() != null) existingUser.setNickName(user.getNickName());
        if (user.getAge() != null) existingUser.setAge(user.getAge());
        if (user.getAvatar() != null) existingUser.setAvatar(user.getAvatar());
        if (user.getSex() != null) existingUser.setSex(user.getSex());
        if (user.getEmail() != null) existingUser.setEmail(user.getEmail());
        if (user.getAddress() != null) existingUser.setAddress(user.getAddress());
// ✅ 设置 createTime 为当前时间（格式：yyyy-MM-dd HH:mm:ss）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        existingUser.setCreateTime(LocalDateTime.now().format(formatter));
        userMapper.updateById(existingUser);
    }


    @Override
    public void delete(Long id) {
        userMapper.deleteById(id);
    }

//    查询用户列表
    @Override
    public Page<UserVO> findPage(ReqPageUserDTO req) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();

        if (req.getUsername() != null && !req.getUsername().trim().isEmpty()) {
            queryWrapper.like(User::getUsername, req.getUsername());
        }
        if (req.getAge() != null) {
            queryWrapper.eq(User::getAge, req.getAge());
        }
        if (req.getSex() != null && !req.getSex().trim().isEmpty()) {
            queryWrapper.eq(User::getSex, req.getSex());
        }

        Page<User> page = new Page<>(req.getPageNum(), req.getPageSize());
        Page<User> userPage = userMapper.selectPage(page, queryWrapper);

        Page<UserVO> voPage = new Page<>();
        voPage.setCurrent(userPage.getCurrent());
        voPage.setSize(userPage.getSize());
        voPage.setTotal(userPage.getTotal());

        List<UserVO> voList = userPage.getRecords().stream().map(user -> {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            return vo;
        }).collect(Collectors.toList());

        voPage.setRecords(voList);
        return voPage;
    }
    /**
     * 获取性别列表
     * @return
     */
    @Override
    public List<Gender> getGenderList() {
        // 创建一个性别列表，模拟数据
        return Arrays.asList(
                new Gender("男", "男"),
                new Gender("女", "女")
        );
    }

    /**
     * 获取用户身份
     * @return
     */
    @Override
    public List<Role> getRoleList(){
        return Arrays.asList(
                new Role("超级管理员","超级管理员"),
                new Role( "普通管理员","普通管理员"),
                new Role("普通用户","普通用户")
        );
    }

    /**
     * 重置密码
     * @param dto
     */
    @Override
    public void resetPassword(ResetPasswordDTO dto) {
        User user = userMapper.selectById(dto.getId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 默认重置密码为 "000000"
        user.setPassword("670b14728ad9902aecba32e22fa4f6bd"); // 可添加加密逻辑
        userMapper.updateById(user);
    }

    /**
     * 批量删除
     * */
    @Override
    public void deleteBatch(List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new ServiceException("400", "删除的ID不能为空");
        }
        userMapper.deleteBatchIds(ids); // 使用 MyBatis-Plus 的批量删除方法
    }

    /**
     * 新增用户
     */
    @Override
    public void addUserWithDefaultValues(User user) {
        // 设置默认密码
        user.setPassword("670b14728ad9902aecba32e22fa4f6bd");  //000000

        // 设置创建时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        user.setCreateTime(LocalDateTime.now().format(formatter));

        userMapper.insert(user);
    }
    //添加批量模块导入的用户
    @Override
    public void importUsersFromExcel(MultipartFile file, boolean isCover) throws Exception {
        try (InputStream is = file.getInputStream();
             Workbook workbook = WorkbookFactory.create(is)) {

            Sheet sheet = workbook.getSheetAt(0);
            List<User> userList = new ArrayList<>();

            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;

                User user = new User();
                user.setUsername(getCellString(row.getCell(0)));
                user.setSex(getCellString(row.getCell(1)));
                user.setAge(getCellInt(row.getCell(2)));
                user.setNickName(getCellString(row.getCell(3)));
                user.setEmail(getCellString(row.getCell(4)));
                user.setAddress(getCellString(row.getCell(5)));
                user.setAvatar(getCellString(row.getCell(6)));
                user.setRole(resolveRoleFromNickName(user.getNickName()));
                user.setPassword("670b14728ad9902aecba32e22fa4f6bd");
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                user.setCreateTime(LocalDateTime.now().format(formatter));

                userList.add(user);
            }

//            if (isCover) {
//                // 先删除已有用户（示例中按账号删除）
////                List<String> usernames = userList.stream().map(User::getUsername).collect(Collectors.toList());
////                remove(new QueryWrapper<User>().in("username", usernames));
//            }
            if (isCover) {
                // 根据用户名批量删除数据库中已存在的用户
                List<String> usernames = userList.stream()
                        .map(User::getUsername)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());

                if (!usernames.isEmpty()) {
                    remove(new QueryWrapper<User>().in("username", usernames));
                }
            }
            saveBatch(userList);
        }
    }
    private Integer resolveRoleFromNickName(String nickName) {
        if ("超级管理员".equals(nickName)) return 1;
        if ("普通管理员".equals(nickName)) return 2;
        return 3; // 默认普通用户
    }


    //导出excel用户数据
    @Override
    public void exportUserData(HttpServletResponse response) {
        List<User> userList = userMapper.selectList(null); // 查询所有用户

        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("用户数据");

            // 表头
            String[] headers = {"ID", "用户账号", "用户身份", "年龄", "头像链接", "性别", "角色编号", "邮箱", "居住地址", "创建时间"};
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                headerRow.createCell(i).setCellValue(headers[i]);
                sheet.autoSizeColumn(i);
            }

            // 写入用户数据
            for (int i = 0; i < userList.size(); i++) {
                User user = userList.get(i);
                Row row = sheet.createRow(i + 1);
                row.createCell(0).setCellValue(user.getId());
                row.createCell(1).setCellValue(user.getUsername());
                row.createCell(2).setCellValue(user.getNickName());
                row.createCell(3).setCellValue(user.getAge() != null ? user.getAge() : 0);
                row.createCell(4).setCellValue(user.getAvatar());
                row.createCell(5).setCellValue(user.getSex());
                row.createCell(6).setCellValue(user.getRole());
                row.createCell(7).setCellValue(user.getEmail());
                row.createCell(8).setCellValue(user.getAddress());
                row.createCell(9).setCellValue(user.getCreateTime() != null ? user.getCreateTime().toString() : "");
            }

            // 设置导出文件属性
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String fileName = URLEncoder.encode("user_data.xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("导出失败：" + e.getMessage(), e);
        }
    }



    @Override
    public void saveBatch(List<User> users) {
        for (User user : users) {
            userMapper.insert(user);
        }
    }

    private String getCellString(Cell cell) {
        if (cell == null) return null;
        cell.setCellType(CellType.STRING);
        return cell.getStringCellValue().trim();
    }

    private Integer getCellInt(Cell cell) {
        if (cell == null) return null;
        if (cell.getCellType() == CellType.NUMERIC) {
            return (int) cell.getNumericCellValue();
        } else {
            try {
                return Integer.parseInt(cell.getStringCellValue());
            } catch (Exception e) {
                return null;
            }
        }
    }

    /**
     *获取所有用户列表
     */
    public PageResult<UserVO> findAllUsers() {
        List<User> users = userMapper.selectList(null);
        List<UserVO> voList = users.stream().map(user -> {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            return vo;
        }).collect(Collectors.toList());
        return new PageResult<>(voList, voList.size());
    }

    //下载excel模板
    @Override
    public void downloadUserTemplate(HttpServletResponse response) {
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("用户导入模板");
            Row headerRow = sheet.createRow(0);

            String[] headers = {"用户账号", "性别", "年龄", "用户身份", "邮箱", "居住地址", "头像"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//            String fileName = URLEncoder.encode("user_template.xlsx", "UTF-8");
//            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            String fileName = URLEncoder.encode("用户导入模板.xlsx", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"; filename*=UTF-8''" + fileName);
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("导出模板失败", e);
        }
    }


    @Override
    public boolean changePassword(PasswordChangeDTO dto) {
        // 根据 ID 查询用户
        User user = userMapper.selectById(dto.getId());
        if (user == null) {
            return false; // 用户不存在
        }

        // 校验原密码是否一致
        if (!dto.getOldPwd().equals(user.getPassword())) {
            return false; // 原密码错误
        }

        // 更新密码
        user.setPassword(dto.getNewPwd()); // 设置新密码
        return userMapper.updateById(user) > 0; // 更新数据库
    }


//    这里来进行一下判断当前用户是否是管理员，如果不是管理员，就不能访问管理端

    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public User getById(Integer userId) {
        return userMapper.selectById(userId);
    }



}
